﻿Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Imports System.Windows.Forms.ToolStripRenderer
Public Class MenuSkin
    Inherits System.Windows.Forms.ToolStripRenderer
    Private mAttachSkin As Boolean = True
    Private mMenuBorderColor As Color = Color.FromArgb(255, 32, 107, 32)
    Private mItemBorderColor As Color = Color.FromArgb(255, 32, 107, 32)
    Private mItemColor1 As Color = Color.FromArgb(255, 243, 248, 237)
    Private mItemColor2 As Color = Color.FromArgb(255, 172, 207, 125)
    Private mItemColor3 As Color = Color.FromArgb(255, 218, 233, 197)
    Private mItemColor4 As Color = Color.FromArgb(255, 250, 252, 247)
    Private mItemColor5 As Color = Color.FromArgb(255, 255, 255)
    Private mItemDownColor1 As Color = Color.FromArgb(255, 245, 202, 154)
    Private mItemDownColor2 As Color = Color.FromArgb(255, 251, 177, 106)
    Private mItemDownColor3 As Color = Color.FromArgb(255, 249, 154, 54)
    Private mItemDownColor4 As Color = Color.FromArgb(255, 253, 240, 175)
    Private mItemDownColor5 As Color = Color.White
    Private mMenuBarColor1 As Color = Color.FromArgb(178, 211, 135)
    Private mMenuBarColor2 As Color = Color.FromArgb(178, 211, 135)
    Private mMenuBarColor3 As Color = Color.FromArgb(178, 211, 135)
    Private mMenuBarColor4 As Color = Color.FromArgb(178, 211, 135)
    Private mMenuBackColor As Color = Color.White
    Private mBackLeftColor1 As Color = Color.FromArgb(174, 208, 128)
    Private mBackLeftColor2 As Color = Color.FromArgb(226, 238, 210)
    Private mBackLeftColor3 As Color = Color.FromArgb(232, 242, 220)
    Private mBackLeftColor4 As Color = Color.FromArgb(255, 255, 255)
    Private mSeparator As Color = Color.FromArgb(255, 204, 199, 186)
    Private TLeft As Integer, mMenuCheck As Bitmap = My.Resources.menu_check
    Private mFullSelected As Boolean = True, mR As Integer = 3
#Region "自定义属性"
    Public Property Separator() As Color
        Get
            Return mSeparator
        End Get
        Set(ByVal value As Color)
            mSeparator = value
        End Set
    End Property
    Public Property MenuBackColor() As Color
        Get
            Return mMenuBackColor
        End Get
        Set(ByVal value As Color)
            mMenuBackColor = value
        End Set
    End Property
    Public Property BackLeftColor4() As Color
        Get
            Return mBackLeftColor4
        End Get
        Set(ByVal value As Color)
            mBackLeftColor4 = value
        End Set
    End Property
    Public Property BackLeftColor3() As Color
        Get
            Return mBackLeftColor3
        End Get
        Set(ByVal value As Color)
            mBackLeftColor3 = value
        End Set
    End Property
    Public Property BackLeftColor2() As Color
        Get
            Return mBackLeftColor2
        End Get
        Set(ByVal value As Color)
            mBackLeftColor2 = value
        End Set
    End Property
    Public Property BackLeftColor1() As Color
        Get
            Return mBackLeftColor1
        End Get
        Set(ByVal value As Color)
            mBackLeftColor1 = value
        End Set
    End Property
    Public Property MenuBarColor4() As Color
        Get
            Return mMenuBarColor4
        End Get
        Set(ByVal value As Color)
            mMenuBarColor4 = value
        End Set
    End Property
    Public Property MenuBarColor3() As Color
        Get
            Return mMenuBarColor3
        End Get
        Set(ByVal value As Color)
            mMenuBarColor3 = value
        End Set
    End Property
    Public Property MenuBarColor2() As Color
        Get
            Return mMenuBarColor2
        End Get
        Set(ByVal value As Color)
            mMenuBarColor2 = value
        End Set
    End Property
    Public Property MenuBarColor1() As Color
        Get
            Return mMenuBarColor1
        End Get
        Set(ByVal value As Color)
            mMenuBarColor1 = value
        End Set
    End Property
    Public Property ItemDownColor5() As Color
        Get
            Return mItemDownColor5
        End Get
        Set(ByVal value As Color)
            mItemDownColor5 = value
        End Set
    End Property
    Public Property ItemDownColor4() As Color
        Get
            Return mItemDownColor4
        End Get
        Set(ByVal value As Color)
            mItemDownColor4 = value
        End Set
    End Property
    Public Property ItemDownColor3() As Color
        Get
            Return mItemDownColor3
        End Get
        Set(ByVal value As Color)
            mItemDownColor3 = value
        End Set
    End Property
    Public Property ItemDownColor2() As Color
        Get
            Return mItemDownColor2
        End Get
        Set(ByVal value As Color)
            mItemDownColor2 = value
        End Set
    End Property
    Public Property ItemDownColor1() As Color
        Get
            Return mItemDownColor1
        End Get
        Set(ByVal value As Color)
            mItemDownColor1 = value
        End Set
    End Property
    Public Property ItemColor5() As Color
        Get
            Return mItemColor5
        End Get
        Set(ByVal value As Color)
            mItemColor5 = value
        End Set
    End Property
    Public Property ItemColor4() As Color
        Get
            Return mItemColor4
        End Get
        Set(ByVal value As Color)
            mItemColor4 = value
        End Set
    End Property
    Public Property ItemColor3() As Color
        Get
            Return mItemColor3
        End Get
        Set(ByVal value As Color)
            mItemColor3 = value
        End Set
    End Property
    Public Property ItemColor2() As Color
        Get
            Return mItemColor2
        End Get
        Set(ByVal value As Color)
            mItemColor2 = value
        End Set
    End Property
    Public Property ItemColor1() As Color
        Get
            Return mItemColor1
        End Get
        Set(ByVal value As Color)
            mItemColor1 = value
        End Set
    End Property
    Public Property ItemBorderColor() As Color
        Get
            Return mItemBorderColor
        End Get
        Set(ByVal value As Color)
            mItemBorderColor = value
        End Set
    End Property
    Public Property MenuBorderColor() As Color
        Get
            Return mMenuBorderColor
        End Get
        Set(ByVal value As Color)
            mMenuBorderColor = value
        End Set
    End Property
#End Region
    Private Sub MenuSkin_RenderButtonBackground(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs) Handles Me.RenderButtonBackground
        If mAttachSkin = False Then Exit Sub
        Dim g As Graphics = e.Graphics, mItem As ToolStripItem = e.Item

    End Sub

    Private Sub MenuSkin_RenderItemBackground(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs) Handles Me.RenderItemBackground

        Dim messageBoxVB As New System.Text.StringBuilder()
        messageBoxVB.AppendFormat("{0} = {1}", "Graphics", e.Graphics)
        messageBoxVB.AppendLine()
        messageBoxVB.AppendFormat("{0} = {1}", "Item", e.Item)
        messageBoxVB.AppendLine()
        messageBoxVB.AppendFormat("{0} = {1}", "ToolStrip", e.ToolStrip)
        messageBoxVB.AppendLine()
        MessageBox.Show(messageBoxVB.ToString(), "RenderItemBackground Event")
    End Sub

    Private Sub MenuSkin_RenderItemText(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemTextRenderEventArgs) Handles Me.RenderItemText
        TLeft = e.TextRectangle.Left
    End Sub

    Private Sub MenuSkin_RenderMenuItemBackground(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs) Handles Me.RenderMenuItemBackground
        If mAttachSkin = False Then Exit Sub
        Dim g As Graphics = e.Graphics, mItem As ToolStripItem = e.Item
        '  g.FillRectangle(New SolidBrush(mItemColor1), mItem.Bounds)
    End Sub



    Private Sub MenuSkin_RenderToolStripBorder(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripRenderEventArgs) Handles Me.RenderToolStripBorder
        If mAttachSkin = False Then Exit Sub
        Dim g As Graphics = e.Graphics
        g.DrawRectangle(New Pen(mMenuBorderColor), New Rectangle(e.AffectedBounds.Left, e.AffectedBounds.Top, e.AffectedBounds.Width - 1, e.AffectedBounds.Height - 1))
    End Sub
    Protected Overrides Sub OnRenderItemCheck(ByVal e As System.Windows.Forms.ToolStripItemImageRenderEventArgs)
        e.Graphics.DrawImage(mMenuCheck, e.ImageRectangle.Location)
        Return
        MyBase.OnRenderItemCheck(e)

    End Sub
    Protected Overrides Sub OnRenderItemImage(ByVal e As System.Windows.Forms.ToolStripItemImageRenderEventArgs)
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality
        MyBase.OnRenderItemImage(e)
    End Sub

    Protected Overrides Sub OnRenderImageMargin(ByVal e As System.Windows.Forms.ToolStripRenderEventArgs) '绘制左侧背景
        Dim LRect As Rectangle = e.AffectedBounds
        Dim LBrush As New LinearGradientBrush(LRect, mBackLeftColor1, mBackLeftColor2, LinearGradientMode.Horizontal)
        Dim ColorL As New ColorBlend
        ColorL.Colors = New Color() {mBackLeftColor1, mBackLeftColor2, mBackLeftColor3, mBackLeftColor4}
        ColorL.Positions = New Single() {0 / 3.0F, 1 / 3.0F, 2 / 3.0F, 3 / 3.0F}
        LBrush.InterpolationColors = ColorL
        TLeft = LRect.Right
        e.Graphics.FillRectangle(LBrush, LRect)
        e.Graphics.DrawLine(New Pen(mSeparator), LRect.Right, LRect.Top, LRect.Right, LRect.Bottom)
        MyBase.OnRenderImageMargin(e)
    End Sub
    Protected Overrides Sub OnRenderToolStripPanelBackground(ByVal e As System.Windows.Forms.ToolStripPanelRenderEventArgs)
        e.Handled = True
        MyBase.OnRenderToolStripPanelBackground(e)
    End Sub
    Protected Overrides Sub OnRenderDropDownButtonBackground(ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs)

        MyBase.OnRenderDropDownButtonBackground(e)
    End Sub
    Protected Overrides Sub OnRenderArrow(ByVal e As System.Windows.Forms.ToolStripArrowRenderEventArgs) 'Menu_Arrow
        '  e.Graphics.FillRectangle(New SolidBrush(Color.Blue), e.ArrowRectangle)
        MyBase.OnRenderArrow(e)
    End Sub
    '================================================================================
    Protected Overrides Sub OnRenderToolStripBackground(ByVal e As ToolStripRenderEventArgs)
        Dim ToolObj As ToolStrip = e.ToolStrip
        If ToolObj.IsDropDown Then
            e.Graphics.FillRectangle(New SolidBrush(mMenuBackColor), e.AffectedBounds)
        Else
            Dim gRect As Rectangle = e.AffectedBounds
            Dim Brush1 As New LinearGradientBrush(gRect, mMenuBarColor1, mMenuBarColor2, LinearGradientMode.Vertical)
            Dim ColorB As New ColorBlend()
            ColorB.Colors = New Color() {mMenuBarColor1, mMenuBarColor2, mMenuBarColor3, mMenuBarColor4}
            ColorB.Positions = New Single() {0 / 3.0F, 1 / 3.0F, 2 / 3.0F, 3 / 3.0F}
            Brush1.InterpolationColors = ColorB
            e.Graphics.FillRectangle(Brush1, gRect)
            Brush1.Dispose()
        End If

        Return
        MyBase.OnRenderToolStripBackground(e)
    End Sub
    Protected Overrides Sub OnRenderMenuItemBackground(ByVal e As System.Windows.Forms.ToolStripItemRenderEventArgs)
        Dim ToolStrip As ToolStrip = e.ToolStrip
        Dim Item As ToolStripItem = e.Item
        If Item.Enabled = False Then
            Return
        End If
        Dim g As Graphics = e.Graphics
        g.SmoothingMode = SmoothingMode.HighQuality
        Dim Rect As Rectangle = New Rectangle(2, 0, e.Item.Size.Width - 4, e.Item.Size.Height - 1)
        Dim gPath As GraphicsPath = CreateRoundPath(Rect, mR)
        If Item.Selected And e.Item.Pressed = False Then
            Dim ItemBrush As New LinearGradientBrush(Rect, mItemColor1, mItemColor1, LinearGradientMode.Vertical)
            Dim ColorI As New ColorBlend
            ColorI.Colors = New Color() {mItemColor1, mItemColor2, mItemColor3, mItemColor4, mItemColor5}
            ColorI.Positions = New Single() {0 / 4.0F, 1 / 4.0F, 2 / 4.0F, 3 / 4.0F, 4 / 4.0F}
            ItemBrush.InterpolationColors = ColorI
            g.FillPath(ItemBrush, gPath)
            g.DrawPath(New Pen(mItemBorderColor), gPath)
        ElseIf Item.Selected And e.Item.Pressed = True Then
            Dim ItemBrush As New LinearGradientBrush(Rect, mItemDownColor1, mItemDownColor1, LinearGradientMode.Vertical)
            Dim ColorI As New ColorBlend
            ColorI.Colors = New Color() {mItemDownColor1, mItemDownColor2, mItemDownColor3, mItemDownColor4, mItemDownColor5}
            ColorI.Positions = New Single() {0 / 4.0F, 1 / 4.0F, 2 / 4.0F, 3 / 4.0F, 4 / 4.0F}
            ItemBrush.InterpolationColors = ColorI
            g.FillPath(ItemBrush, gPath)
            g.DrawPath(New Pen(mItemBorderColor), gPath)
        End If
        gPath.Dispose()
        ' End If
        MyBase.OnRenderMenuItemBackground(e)
    End Sub
    Protected Overrides Sub OnRenderSeparator(ByVal e As System.Windows.Forms.ToolStripSeparatorRenderEventArgs) '绘制分割线
        e.Graphics.DrawLine(New Pen(mSeparator), New Point(TLeft, 0), New Point(e.Item.Size.Width, 0))
        MyBase.OnRenderSeparator(e)
    End Sub
    Public Function CreateRoundPath(ByVal Rect As Rectangle, ByVal R As Integer)
        Dim ResultPath As GraphicsPath = New GraphicsPath(FillMode.Alternate)
        Dim L As Integer = 2 * R
        Dim TmpRect As Rectangle = New Rectangle(Rect.Location, New Size(L, L))
        With ResultPath
            .AddArc(TmpRect, 180.0F, 90.0F)
            .AddLine(New Point(Rect.Left + R, Rect.Top), New Point(Rect.Right - R, Rect.Top))
            TmpRect.X = Rect.Right - L
            .AddArc(TmpRect, 270.0F, 90.0F)
            .AddLine(New Point(Rect.Right, Rect.Top + R), New Point(Rect.Right, Rect.Bottom - R))
            TmpRect.Y = Rect.Bottom - L
            .AddArc(TmpRect, 0.0F, 90.0F)
            .AddLine(New Point(Rect.Right - R, Rect.Bottom), New Point(Rect.Left + R, Rect.Bottom))
            TmpRect.X = Rect.Left
            .AddArc(TmpRect, 90.0F, 90.0F)
            .AddLine(New Point(Rect.Left, Rect.Bottom - R), New Point(Rect.Left, Rect.Top + R))
            Return ResultPath
        End With
    End Function
End Class
